"mqtt信息队列组件"

__author__ = "zwj"

import os, sys, traceback

parent_path = os.path.abspath(os.path.join(__file__, *([".."] * 5)))
sys.path.insert(0, parent_path)

import paho.mqtt.client as mqtt
import time
import json
from typing import Dict
from core.task.modules.processors.base_processor import BaseProcessor
from core.utils.logger import logging


class MqttRequest(BaseProcessor):
    """将数据传入mqtt消息队列
    keys = {
        in: 输入数据索引key
    }
    """

    def __init__(
        self,
        keys,
        MqttRequest_host=None,
        MqttRequest_port=None,
        MqttRequest_user=None,
        MqttRequest_passwd=None,
        MqttRequest_topic=None,
    ) -> None:
        self.status = 0
        self.keys = keys
        self.host = MqttRequest_host
        self.port = MqttRequest_port
        self.user = MqttRequest_user
        self.passwd = MqttRequest_passwd
        self.topic = MqttRequest_topic

    def on_disconnect(self, client, userdata, flags, reason_code, properties):
        logging.error(f"MQTT 断连 : {reason_code}")

        if reason_code != 0:
            logging.info("MQTT 尝试自动重连...")
            while True:
                try:
                    self.client.reconnect()
                    logging.info("MQTT 重连成功!")
                    break
                except Exception as e:
                    logging.warning(f"MQTT 重连失败: {e}")
                    time.sleep(5)  # 等待5秒再尝试重新连接

    def _init_check(self):
        assert "in" in self.keys
        assert not self.host is None
        assert not self.user is None
        assert not self.passwd is None
        assert not self.port is None
        assert not self.topic is None
        # 尝试连接 mqtt
        try:
            # mqtt 初始化
            self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
            self.client.on_disconnect = self.on_disconnect
            self.client.username_pw_set(self.user, self.passwd)
            self.client.connect(self.host, self.port, 10)
            # 启动网络循环
            self.client.loop_start()
        except:
            raise Exception(traceback.format_exc())

    def _set(self, data: Dict):
        if data.get("MqttRequest_host", False):
            self.host = data["MqttRequest_host"]
        if data.get("MqttRequest_port", False):
            self.port = data["MqttRequest_port"]
        if data.get("MqttRequest_user", False):
            self.user = data["MqttRequest_user"]
        if data.get("MqttRequest_passwd", False):
            self.passwd = data["MqttRequest_passwd"]
        if data.get("MqttRequest_topic", False):
            self.topic = data["MqttRequest_topic"]

    def _call(self, data: Dict) -> Dict:
        # 发现输入值有
        if data.get(self.keys["in"], False):
            mqtt_message = data.pop(self.keys["in"])
            mqtt_string = json.dumps(mqtt_message)
            # logging.info(f"输出 mqtt 消息 : {mqtt_string}")
            # 发送消息
            self.client.publish(self.topic, payload=mqtt_string, qos=0, retain=False)

        return data

    def _close(self):
        self.client.loop_stop()
        self.client.disconnect()


if __name__ == "__main__":
    mqtt_request = MqttRequest(
        MqttRequest_host="36.138.254.186",
        MqttRequest_port=1883,
        MqttRequest_user="admin",
        MqttRequest_passwd="public",
        MqttRequest_topic="sxgs_261_command",
        keys={"in": "point_in_screen"},
    )
    data = {
        "MqttRequest_host": "36.138.254.186",
        "MqttRequest_port": 1883,
        "MqttRequest_user": "admin",
        "MqttRequest_passwd": "public",
        "MqttRequest_topic": "sxgs_261_command",
    }
    mqtt_request.set(data)
    mqtt_request.start()
    # time.sleep(10)
    # mqtt_request.close()

    data = {
        "point_in_screen": {
            "x": 0.5,
            "y": 0.5,
        }
    }
    mqtt_request(data)

    while True:
        time.sleep(1)
